﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Pavilion.GameTools;
using Microsoft.Xna.Framework;

namespace Pavilion.Locks
{
    class DistanceLock : ILock
    {
        public float Distance { get; set; }
        public string GameItemName { get; set; }

        public ILock Clone()
        {
            return new DistanceLock()
            {
                GameItemName = this.GameItemName,
                Distance = this.Distance,
            };
        }

        public void Deserialize(XElement lockElement, string resourceName)
        {
            Distance = GameEngine.ParseObject<float>(lockElement.Attribute("Distance").Value);
        }

        public XElement Serialize()
        {
            XElement lockElement = new XElement("Lock");

            lockElement.Add(new XAttribute("Distance", Distance));

            return lockElement;
        }

        public LockMonitorBase CreateLockMonitor(GameItem gameItem)
        {
            return new DistanceLockMonitor(this, gameItem.ObtainTool<PhysicalTypeTool>().PolygonData);
        }

        public override string ToString()
        {
            return this.GetType().Name;
        }

        public class DistanceLockMonitor : LockMonitorBase
        {
            public override ILock Lock { get { return distanceLock; } }

            private PhysicalData physicalData;
            private DistanceLock distanceLock;
            private Vector2 startingPosition;

            public DistanceLockMonitor(DistanceLock distanceLock, PhysicalData physicalData)
            {
                this.distanceLock = distanceLock;
                this.physicalData = physicalData;

                startingPosition = physicalData.Position;
            }

            public override void Dispose()
            {
                physicalData.PositionChanged -= PhysicalData_PositionChanged;
                physicalData = null;
                distanceLock = null;
            }

            public override void Load(GameItem gameItem)
            {
                physicalData.PositionChanged += PhysicalData_PositionChanged;

                UpdateLock();
            }

            public override void UpdateLock()
            {
                float distance = Vector2.Distance(physicalData.Position, startingPosition);

                IsOpen = distance > this.distanceLock.Distance;
            }

            private void PhysicalData_PositionChanged(PhysicalData physicalData) { UpdateLock(); }
        }
    }
}
